package cn.aws360.boot.system.starter.controller;

import cn.aws360.boot.base.api.pojo.properties.AppProperties;
import cn.aws360.boot.base.api.pojo.response.ResultModel;
import cn.aws360.boot.system.api.pojo.response.SysUserThirdModel;
import cn.aws360.boot.system.api.pojo.response.ThirdItemModel;
import cn.aws360.boot.system.biz.service.SysUserThirdService;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.xkcoding.justauth.AuthRequestFactory;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

import static cn.aws360.boot.system.api.constant.SysConstant.*;


/**
 * @author junnan
 */
@Slf4j
@Controller
@RequiredArgsConstructor
@RequestMapping("/oauth")
@ApiSupport(order = MODULE_USER_CODE)
@Api(value = MODULE_USER_NAME, tags = MODULE_USER_TAGS)
public class OauthController {

    private final AuthRequestFactory factory;
    private final SysUserThirdService sysUserThirdService;

    private final AppProperties appProperties;
    private static final String LINK_PATH = "%s/oauth/login/%s";

    @ResponseBody
    @GetMapping("/list")
    @ApiOperation(value = "三方列表", hidden = true)
    public ResultModel<List<ThirdItemModel>> list() {
        String domain = appProperties.getDomain();
        List<String> sourceList = factory.oauthList();
        List<ThirdItemModel> itemModelList = sourceList.stream().map(s -> ThirdItemModel.builder()
                .name(s.toLowerCase())
                .link(String.format(LINK_PATH, domain, s.toLowerCase())).build())
                .collect(Collectors.toList());
        return ResultModel.ok(itemModelList);
    }

    @GetMapping("/login/{source}")
    @ApiOperation(value = "三方登录", hidden = true)
    public void login(@PathVariable String source, HttpServletResponse response) throws IOException {
        AuthRequest authRequest = factory.get(source);
        response.sendRedirect(authRequest.authorize(AuthStateUtils.createState()));
    }

    @RequestMapping("/{source}/callback")
    @ApiOperation(value = "三方回调接口", hidden = true)
    public String callback(@PathVariable String source, AuthCallback callback, Model model) {
        AuthRequest authRequest = factory.get(source);
        AuthResponse<?> response = authRequest.login(callback);
        if (response.ok()) {
            AuthUser authUser = (AuthUser) response.getData();
            SysUserThirdModel userThirdModel = sysUserThirdService.saveAuthUser(authUser);
            model.addAttribute("app", appProperties);
            model.addAttribute("source", source);
            model.addAttribute("userThirdModel", userThirdModel);
            return "third-bind";
        }
        return "/login";
    }

}
